home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 23 / AACD 23.iso / AACD / Sound / RAPlay / src / RAPlay.c < prev    next >
C/C++ Source or Header  |  2001-06-15  |  9KB  |  383 lines

  1. #define __USE_SYSBASE
  2. #include <stdio.h>
  3. #include <proto/dos.h>
  4. #include <proto/exec.h>
  5. #include <exec/types.h>
  6. #include <exec/memory.h>
  7. #include <proto/asyncio.h>
  8. #include <proto/ahi.h>
  9.  
  10. #ifdef __PPC__
  11. #include <powerup/gcclib/powerup_protos.h>
  12. #undef SetSignal
  13. #define SetSignal PPCSetSignal
  14. #endif
  15.  
  16. #include "common.h"
  17.  
  18. static const char version[]="$VER: RAPlay 2.0 (15.06.01) The Amiga RealAudio 14.4/28.8 player/decoder, thanks to all!";
  19. ULONG __nocommandline;
  20. ULONG __stack = 16384;
  21.  
  22. #if 0
  23. BOOL FastTable = 0;
  24. #endif
  25.  
  26. struct Library    *AsyncIOBase = NULL;
  27. AsyncFile         *InputFile   = NULL;
  28. AsyncFile         *OutputFile  = NULL;
  29. Real_144          *Real144     = NULL;
  30. Real_288          *Real288     = NULL;
  31.  
  32. struct MsgPort    *AHImp       = NULL;
  33. struct AHIRequest *AHIio       = NULL;
  34. struct AHIRequest *AHIio2      = NULL;
  35. BYTE               AHIDevice   = -1;
  36.  
  37. struct RDArgs     *rdargs      = NULL;
  38. #if 0
  39. STRPTR Template = "INPUT,OUTPUT,U=UNIT/K/N,FAST/S";
  40. enum { TEM_INPUT, TEM_OUTPUT, TEM_UNIT, TEM_FAST, TEM_NUMARGS };
  41. #else
  42. STRPTR Template = "INPUT,OUTPUT,U=UNIT/K/N";
  43. enum { TEM_INPUT, TEM_OUTPUT, TEM_UNIT, TEM_NUMARGS };
  44. #endif
  45.  
  46. signed short *outbuf=NULL,*dubbuf=NULL;
  47.  
  48. #ifndef __GNUC__
  49. static int break_cleanup(void)
  50. {
  51.     /* Just a dummy so atexit() will work */
  52.     return 1;
  53. }
  54. #endif
  55.  
  56. static void exit_cleanup(void)
  57. {
  58.     if(outbuf);
  59.     {
  60.         FreeMem(outbuf,AUDIOBUFFER*sizeof(short));
  61.         outbuf = NULL;
  62.     }
  63.  
  64.     if(dubbuf);
  65.     {
  66.         FreeMem(dubbuf,AUDIOBUFFER*sizeof(short));
  67.         dubbuf = NULL;
  68.     }
  69.  
  70.     if(Real144);
  71.     {
  72.         free_144(Real144);
  73.         Real144 = NULL;
  74.     }
  75.  
  76.     if(Real288);
  77.     {
  78.         free_288(Real288);
  79.         Real288 = NULL;
  80.     }
  81.  
  82.     if(InputFile);
  83.     {
  84.         CloseAsync(InputFile);
  85.         InputFile = NULL;
  86.     }
  87.  
  88.     if(OutputFile);
  89.     {
  90.         CloseAsync(OutputFile);
  91.         OutputFile = NULL;
  92.     }
  93.  
  94.     if(AsyncIOBase)
  95.     {
  96.         CloseLibrary(AsyncIOBase);
  97.         AsyncIOBase = NULL;
  98.     }
  99.  
  100.     if(!AHIDevice)
  101.     {
  102.         CloseDevice((struct IORequest *)AHIio);
  103.         AHIDevice = -1;
  104.     }
  105.  
  106.     if(AHIio)
  107.     {
  108.         DeleteIORequest((struct IORequest *)AHIio);
  109.         AHIio = NULL;
  110.     }
  111.  
  112.     if(AHIio2)
  113.     {
  114.         DeleteIORequest((struct IORequest *)AHIio2);
  115.         AHIio2 = NULL;
  116.     }
  117.  
  118.     if(AHImp)
  119.     {
  120.         DeleteMsgPort(AHImp);
  121.         AHImp = NULL;
  122.     }
  123.  
  124.     if(rdargs)
  125.     {
  126.         FreeArgs(rdargs);
  127.         rdargs = NULL;
  128.     }
  129. }
  130.  
  131. void Fail(STRPTR reason)
  132. {
  133.     BPTR StdErr;
  134.  
  135.     if ((StdErr = Open("CONSOLE:", MODE_NEWFILE)))
  136.     {
  137.         FPrintf(StdErr, "%s\n", reason);
  138.         Close(StdErr);
  139.     }
  140.  
  141.     exit(20);
  142. }
  143.  
  144. int main(void)
  145. {
  146.   ULONG unit=0;
  147.   BOOL terminated=FALSE;
  148.   ULONG signals,AHIcount=0;
  149.   struct AHIRequest *link = NULL;
  150.   LONG ArgArray[TEM_NUMARGS];
  151.   BPTR StdIn, StdOut;
  152.   unsigned int s,x,bufsiz,size,blocksize,chunksize;
  153.   unsigned char in[DATACHUNK2];
  154.   unsigned char deint[DATACHUNK2];
  155.   void *tmp;
  156.  
  157.   for(x=0;x<TEM_NUMARGS;ArgArray[x++]=NULL);
  158.   if(!(rdargs=ReadArgs(Template,ArgArray,NULL))) Fail("Unable to read arguments.");
  159.  
  160.   StdIn  = Input();
  161.   StdOut = Output();
  162.  
  163.   if(!ArgArray[TEM_INPUT])
  164.   {
  165.     if(IsInteractive(StdIn)) Fail("No input specified.");
  166.     else if(IsInteractive(StdOut)) Fail("Please redirect output or use proper arguments instead.");
  167.   }
  168.  
  169.   if(ArgArray[TEM_UNIT]) unit=*((ULONG *)ArgArray[TEM_UNIT]);
  170.   if(unit>3) Fail("Illegal unit number!");
  171.  
  172. #if 0
  173.   if(ArgArray[TEM_FAST]) FastTable=1;
  174. #endif
  175.  
  176.   if(ArgArray[TEM_INPUT])
  177.   {
  178.     if(!(AsyncIOBase=OpenLibrary("asyncio.library", 39))) Fail("Unable to open asyncio.library.");
  179.  
  180. #ifndef __GNUC__
  181.     onbreak(break_cleanup);
  182. #endif
  183.     atexit(exit_cleanup);
  184.  
  185.     if(!(InputFile=OpenAsync((STRPTR)ArgArray[TEM_INPUT], MODE_READ, 16384))) Fail("Unable to open input file.");
  186.  
  187.     if(ArgArray[TEM_OUTPUT])
  188.     {
  189.       if(!(OutputFile=OpenAsync((STRPTR)ArgArray[TEM_OUTPUT], MODE_WRITE, 32768))) Fail("Unable to open output file.");
  190.     }
  191.     else
  192.     {
  193.       if(AHImp=CreateMsgPort())
  194.         if(AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest)))
  195.         {
  196.           AHIio->ahir_Version = 4;
  197.           AHIDevice=OpenDevice(AHINAME,unit,(struct IORequest *)AHIio,NULL);
  198.         }
  199.       if(AHIDevice) Fail("Unable to open ahi.device v4");
  200.  
  201.       if(!(AHIio2=AllocMem(sizeof(struct AHIRequest), MEMF_ANY))) Fail("Unable to allocate needed memory.");
  202.       CopyMem(AHIio, AHIio2, sizeof(struct AHIRequest));
  203.     }
  204.  
  205.     if(ReadAsync(InputFile,in,6) <= 0) Fail("Unexpected EOF or error while reading.");
  206.   }
  207.   else Read(StdIn,in,6);
  208.  
  209.   if(in[0]=='.'&&in[1]=='R'&&in[2]=='M'&&in[3]=='F') Fail("RealMedia streams are not supported!!!");
  210.   if(in[0]=='.'&&in[1]=='r'&&in[2]=='a'&&in[3]==0xfd)
  211.   {
  212.     if(in[5]==4)
  213.     {
  214.       if(ArgArray[TEM_INPUT])
  215.       {
  216.         if(ReadAsync(InputFile,in,55) <= 0) Fail("Unexpected EOF or error while reading.");
  217.       }
  218.       else Read(StdIn,in,55);
  219.  
  220.       if(in[54]=='0') Fail("Int0 28.8 streams are not supported!!!");
  221.       if(in[54]=='r') Fail("RealMedia streams are not supported!!!");
  222.  
  223.       x=(in[12]<<24|in[13]<<16|in[14]<<8|in[15])-45;
  224.  
  225.       if(ArgArray[TEM_INPUT])
  226.       {
  227.         if(ReadAsync(InputFile,in,x) <= 0) Fail("Unexpected EOF or error while reading.");
  228.       }
  229.       else Read(StdIn,in,x);
  230.  
  231.       blocksize=DATABLOCK2;
  232.       chunksize=DATACHUNK2;
  233.       Real288 = init_288();
  234.     }
  235.     else if(in[5]==3)
  236.     {
  237.       if(ArgArray[TEM_INPUT])
  238.       {
  239.         if(ReadAsync(InputFile,in,2) <= 0) Fail("Unexpected EOF or error while reading.");
  240.       }
  241.       else Read(StdIn,in,2);
  242.  
  243.       while(in[0])
  244.       {
  245.         if(ArgArray[TEM_INPUT])
  246.         {
  247.           if(ReadAsync(InputFile,in,256) <= 0) Fail("Unexpected EOF or error while reading.");
  248.         }
  249.         else Read(StdIn,in,256);
  250.       }
  251.  
  252.       if(ArgArray[TEM_INPUT])
  253.       {
  254.         if(ReadAsync(InputFile,in,in[1]) <= 0) Fail("Unexpected EOF or error while reading.");
  255.       }
  256.       else Read(StdIn,in,in[1]);
  257.  
  258.       blocksize=DATABLOCK1;
  259.       chunksize=DATACHUNK1;
  260.       Real144 = init_144();
  261.     }
  262.     else Fail("Not a 14.4 or 28.8 stream!!!");
  263.   }
  264.   else Fail("Unrecognized format!!!");
  265.  
  266.   if(AHImp) if(!(dubbuf = (signed short *)AllocMem(AUDIOBUFFER*sizeof(short), MEMF_ANY | MEMF_CLEAR))) Fail("Unable to allocate needed memory.");
  267.   if(!(outbuf=(signed short *)AllocMem(AUDIOBUFFER*sizeof(short), MEMF_ANY | MEMF_CLEAR))) Fail("Unable to allocate needed memory.");
  268.  
  269.   if(ArgArray[TEM_INPUT])
  270.   {
  271.     while((s=size=ReadAsync(InputFile,in,chunksize))>0)
  272.     {
  273.       bufsiz=0;
  274.       if (!(size/=blocksize)) break;
  275.  
  276.       if(blocksize==DATABLOCK1) {
  277.         for(x=0;x<size;x++)
  278.         {
  279.           decode_144(Real144,in+blocksize*x,&outbuf[bufsiz]);
  280.           bufsiz+=AUDIOBLOCK;
  281.         }
  282.       } else {
  283.         deinterleave(in,deint,s);
  284.         for(x=0;x<size;x++)
  285.         {
  286.           decode_288(Real288,deint+blocksize*x,&outbuf[bufsiz]);
  287.           bufsiz+=AUDIOBLOCK;
  288.         }
  289.       }
  290.  
  291.       if(AHImp)
  292.       {
  293.         AHIio->ahir_Std.io_Message.mn_Node.ln_Pri = 0;
  294.         AHIio->ahir_Std.io_Command  = CMD_WRITE;
  295.         AHIio->ahir_Std.io_Data     = outbuf;
  296.         AHIio->ahir_Std.io_Length   = bufsiz*sizeof(short);
  297.         AHIio->ahir_Std.io_Offset   = 0;
  298.         AHIio->ahir_Frequency       = 8000;
  299.         AHIio->ahir_Type            = AHIST_M16S;
  300.         AHIio->ahir_Volume          = 0x10000;
  301.         AHIio->ahir_Position        = 0x8000;
  302.         AHIio->ahir_Link            = link;
  303.         SendIO((struct IORequest *) AHIio);
  304.         AHIcount++;
  305.  
  306.         if(link)
  307.         {
  308.           signals=Wait(SIGBREAKF_CTRL_C | (1L << AHImp->mp_SigBit));
  309. #ifdef __PPC__
  310.           if(SetSignal(0,0) & SIGBREAKF_CTRL_C)
  311. #else
  312.           if(signals & SIGBREAKF_CTRL_C)
  313. #endif
  314.           {
  315.             terminated=TRUE;
  316.             break;
  317.           }
  318.           if(WaitIO((struct IORequest *) link)) Fail("I/O request failed.");
  319.         }
  320.  
  321.         link   = AHIio;
  322.  
  323.         tmp    = outbuf;
  324.         outbuf = dubbuf;
  325.         dubbuf = tmp;
  326.  
  327.         tmp    = AHIio;
  328.         AHIio  = AHIio2;
  329.         AHIio2 = tmp;
  330.       }
  331.       else
  332.       {
  333.         WriteAsync(OutputFile,outbuf,bufsiz*sizeof(short));
  334.         if(SetSignal(0,0) & SIGBREAKF_CTRL_C) break;
  335.       }
  336.     }
  337.   }
  338.   else
  339.   {
  340.     while((s=size=Read(StdIn,in,chunksize))>0)
  341.     {
  342.       bufsiz=0;
  343.       if (!(size/=blocksize)) break;
  344.  
  345.       if(blocksize==DATABLOCK1) {
  346.         for(x=0;x<size;x++)
  347.         {
  348.           decode_144(Real144,in+blocksize*x,&outbuf[bufsiz]);
  349.           bufsiz+=AUDIOBLOCK;
  350.         }
  351.       } else {
  352.         deinterleave(in,deint,s);
  353.         for(x=0;x<size;x++)
  354.         {
  355.           decode_288(Real288,deint+blocksize*x,&outbuf[bufsiz]);
  356.           bufsiz+=AUDIOBLOCK;
  357.         }
  358.       }
  359.  
  360.       Write(StdOut,outbuf,bufsiz*sizeof(short));
  361.       if(SetSignal(0,0) & SIGBREAKF_CTRL_C) break;
  362.     }
  363.   }
  364.  
  365.   if(AHIcount)
  366.   {
  367.     if(terminated)
  368.     {
  369.       AbortIO((struct IORequest *) AHIio);
  370.       WaitIO((struct IORequest *) AHIio);
  371.  
  372.       if(AHIcount>1)
  373.       {
  374.         AbortIO((struct IORequest *) AHIio2);
  375.         WaitIO((struct IORequest *) AHIio2);
  376.       }
  377.     }
  378.     else WaitIO((struct IORequest *) AHIio2);
  379.   }
  380.  
  381.   return 0;
  382. }
  383.